package com.durian.base.net.request;

import com.durian.base.net.HttpConfig;
import com.durian.base.net.HttpRequestParams;
import com.durian.base.net.HttpResponse;
import com.durian.base.net.Utils;
import com.durian.base.net.cache.HttpCacheManager;
import com.durian.base.net.cache.IHttpCacheManager;
import com.durian.base.utils.GsonUtils;
import com.durian.base.utils.MD5;
import com.durian.base.utils.StringUtils;

import java.io.File;
import java.net.SocketTimeoutException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Request;

/**
 * 说明：OkSyncHttpTask
 * <p/>
 * 作者：Fanly
 * <p/>
 * 类型：Class
 * <p/>
 * 时间：2020/04/03 14:15
 * <p/>
 * 版本：version 1.0
 */
public abstract class OkSyncHttpTask extends AbstractSyncHttpTask {

    protected HttpRequestParams mRequestParams;
    protected Call              mCall;
    protected long              timeOut = HttpConfig.Constant.TIME_OUT;

    public OkSyncHttpTask(String url) {
        super(url);
    }

    private OkSyncHttpTask checkRequestParams(){
        if (mRequestParams == null){
            if (HttpConfig.get().getDefultRequestFactroy() != null){
                mRequestParams = HttpConfig.get().getDefultRequestFactroy().createRequest().getHttpRequestParams();
            }
            if (mRequestParams == null){
                mRequestParams = new HttpRequestParams();
            }
        }
        return this;
    }

    /**
     * 单位秒
     *
     * @param timeOut
     * @return
     */
    public OkSyncHttpTask setTimeOut(int timeOut) {
        doSetTimeOut(timeOut);
        return this;
    }

    /**
     * 创建 Request.Builder
     *
     * @return
     */
    public abstract Request.Builder createRequestBuilder();

    protected void doSetTimeOut(long timeOut) {
        this.timeOut = timeOut;
    }

    @Override
    protected HttpResponse doInBackground() {
        try {
            Request.Builder builder = createRequestBuilder();
            if (builder == null){
                return HttpResponse.nullResponse();
            }else {
                if (timeOut == HttpConfig.Constant.TIME_OUT) {
                    mCall = HttpConfig.get().client().newCall(builder.build());
                } else {
                    mCall = HttpConfig.get().client().newBuilder().readTimeout(timeOut, TimeUnit.SECONDS).writeTimeout(timeOut, TimeUnit.SECONDS).connectTimeout(timeOut, TimeUnit.SECONDS).retryOnConnectionFailure(true).build().newCall(builder.build());
                }
                return HttpResponse.response(mCall.execute());
            }
        } catch (Exception e) {
            Utils.eLog(e);
            if (e instanceof SocketTimeoutException || (e != null && e instanceof InterruptedException && (e.getMessage() != null && "timeout".equals(e.getMessage().toLowerCase())))) {
                return HttpResponse.timeOut(e);
            } else {
                return HttpResponse.unkown(e);
            }
        }
    }

    @Override
    protected void doCancelTask() {
        super.doCancelTask();
        if (mCall != null && !mCall.isCanceled()) {
            try {
                mCall.cancel();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Params
     **/

    public OkSyncHttpTask setReqeust(IBaseRequest baseRequest) {
        if (baseRequest != null) {
            mRequestParams = baseRequest.getHttpRequestParams();
        }
        return this;
    }

    /**
     * Params
     **/

    public OkSyncHttpTask setReqeustParams(HttpRequestParams params) {
        if (params != null) {
            mRequestParams = params;
        }
        return this;
    }

    public OkSyncHttpTask putParams(String key, int value) {
        checkRequestParams();
        mRequestParams.putParams(key, value);
        return this;
    }

    public OkSyncHttpTask putParams(String key, int value,boolean isAdd) {
        checkRequestParams();
        if (isAdd){
            mRequestParams.putParams(key, value);
        }
        return this;
    }

    public OkSyncHttpTask putParams(String key, double value) {
        checkRequestParams();
        mRequestParams.putParams(key, value);
        return this;
    }

    public OkSyncHttpTask putParams(String key, boolean value) {
        checkRequestParams();
        mRequestParams.putParams(key, value);
        return this;
    }

    public OkSyncHttpTask putParams(String key, long value) {
        checkRequestParams();
        mRequestParams.putParams(key, value);
        return this;
    }

    public OkSyncHttpTask putParams(String key, String value) {
        checkRequestParams();
        if (value != null){
            mRequestParams.putParams(key, value);
        }
        return this;
    }

    public OkSyncHttpTask putFile(String key, File file) {
        checkRequestParams();
        mRequestParams.putFile(key, file);
        return this;
    }

    public OkSyncHttpTask putFile(String key, File file, String contentType) {
        checkRequestParams();
        mRequestParams.putFile(key, file, contentType);
        return this;
    }

    public OkSyncHttpTask putFiles(String key, List<File> files) {
        checkRequestParams();
        mRequestParams.putFiles(key, files);
        return this;
    }

    /**
     * Header
     **/
    public OkSyncHttpTask putHeader(String key, int value) {
        checkRequestParams();
        mRequestParams.putHeader(key, value);
        return this;
    }

    public OkSyncHttpTask putHeader(String key, double value) {
        checkRequestParams();
        mRequestParams.putHeader(key, value);
        return this;
    }

    public OkSyncHttpTask putHeader(String key, String value) {
        checkRequestParams();
        mRequestParams.putHeader(key, value);
        return this;
    }

    public OkSyncHttpTask setCacheKey(String cacheKey){
        this.cacheKey = cacheKey;
        return this;
    }

    @Override
    public String getCacheKey() {
        return MD5.getMD5(cacheKey+ GsonUtils.toJson(getRequestParams()));
    }

    public OkSyncHttpTask setCacheManager(IHttpCacheManager manager){
        this.mHttpCacheManager = manager;
        return this;
    }

    @Override
    public String getCacheUrl() {
        return url;
    }

    @Override
    public IHttpCacheManager getHttpCacheManager() {
        return mHttpCacheManager;
    }

    public HttpRequestParams getRequestParams() {
        checkRequestParams();
        return mRequestParams;
    }

    @Override
    public HttpResponse start() {
        HttpResponse response = doInBackground();
        if (response != null && response.isSuccess()){
            String result = response.getResult();
            HttpCacheManager.saveCache(this,result);
            return response;
        }else {
            String result = HttpCacheManager.readCache(this);
            if (StringUtils.isNotEmpty(result)){
                return HttpResponse.fromCache(response,result);
            }else {
                return response;
            }
        }
    }
}
